package com.zh.auth.controller;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.zh.auth.domain.dto.*;
import com.zh.auth.service.*;
import com.zh.common.annotation.NeedAuth;
import com.zh.common.annotation.NeedPermission;
import com.zh.common.annotation.NeedRoles;
import com.zh.common.annotation.Operator;
import com.zh.common.constant.AuthConstant;
import com.zh.common.dto.IpDto;
import com.zh.web.base.ApiResult;
import com.zh.web.base.BaseController;
import com.zh.web.domain.auth.dto.AddRole2UserDto;
import com.zh.web.domain.auth.dto.DelRole2UserDto;
import com.zh.web.domain.auth.vo.UserVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.Map;

@RestController
@RequestMapping("/auth")
@RequiredArgsConstructor
@Api(tags = "认证服务")
@Operator
@Validated
public class AuthController extends BaseController {
    private final AuthService authService;
    private final UserRoleService userRoleService;

    @ApiOperationSupport(order = 1)
    @GetMapping("/getPublicKey")
    @ApiOperation(value = "获取公钥")
    public ApiResult<String> getPublicKey() {
        return buildSuccessPackage(authService.getPublicKey());
    }

    @ApiOperationSupport(order = 2)
    @GetMapping("/getPrivateKey")
    @ApiOperation(value = "获取私钥", hidden = true)
    public ApiResult<String> getPrivateKey() {
        return buildSuccessPackage(authService.getPrivateKey());
    }

    @ApiOperationSupport(order = 3)
    @PostMapping("/login")
    @ApiOperation(value = "登录", notes = "响应头返回token,响应体返回用户信息，初始化用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "Bearer token", dataType = "string", paramType = "header")
    })
    public ApiResult<UserVo> login(HttpServletRequest request, HttpServletResponse response, @RequestBody LoginDto loginDto) throws Exception {
        IpDto ipDto = getIpAddress(request);
        return buildSuccessPackage(authService.login(request, response, loginDto, ipDto));
    }

    @ApiOperationSupport(order = 4)
    @PostMapping("/register")
    @ApiOperation(value = "注册")
    public ApiResult<String> register(@Valid @RequestBody RegisterDto registerDto) {
        return buildSuccessPackage(authService.register(registerDto));
    }

    @ApiOperationSupport(order = 5)
    @GetMapping("/refreshToken")
    @ApiOperation(value = "刷新token", notes = "短session使用，目前没用", hidden = true)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "Bearer token", required = true, dataType = "string", paramType = "header")
    })
    public ApiResult<String> refreshToken(HttpServletRequest request, HttpServletResponse response) {
        return buildSuccessPackage(authService.refreshToken(request, response));
    }

    @GetMapping("/check")
    @ApiOperation("检查token是否有效")
    public ApiResult<Boolean> checkToken(@RequestParam("authToken") String authToken) {
        return buildSuccessPackage(authService.checkToken(authToken));
    }

    @ApiOperationSupport(order = 6)
    @ApiOperation(value = "退出登录", notes = "提供token可踢出")
    @GetMapping("/logout")
    public ApiResult<String> logout(@RequestParam String authToken) {
        return buildSuccessPackage(authService.invalidateToken(authToken));
    }

    @ApiOperationSupport(order = 7)
    @GetMapping("/getSessionByToken")
    @ApiOperation(value = "根据token获取用户session", hidden = true)
    public ApiResult<Map<String, Object>> getSessionByToken(String token) {
        return buildSuccessPackage(authService.getUserSessionByToken(token));
    }

    @ApiOperationSupport(order = 8)
    @PostMapping("/role2User/add")
    @ApiOperation(value = "添加角色到用户,需要管理员或者insert", hidden = true)
    @NeedAuth(roles = {@NeedRoles(value = AuthConstant.ADMIN)}, permissions = {@NeedPermission(value = AuthConstant.INSERT)})
    @ApiImplicitParams(
            @ApiImplicitParam(name = "Authorization", value = "Bearer token", required = true, dataType = "string", paramType = "header")
    )
    public ApiResult<String> addRole2User(@Valid @RequestBody AddRole2UserDto addRole2UserDto) {
        addRole2UserDto.setCreateOperator(operator);
        addRole2UserDto.setUpdateOperator(operator);
        return buildMsgPackage(userRoleService.addRole2User(addRole2UserDto));
    }

    @ApiOperationSupport(order = 9)
    @DeleteMapping("/role2User/delete")
    @ApiOperation(value = "删除用户拥有角色,需要管理员或者delete", hidden = true)
    @NeedAuth(roles = {@NeedRoles(value = AuthConstant.ADMIN)}, permissions = {@NeedPermission(value = AuthConstant.DELETE)})
    @ApiImplicitParams(
            @ApiImplicitParam(name = "Authorization", value = "Bearer token", required = true, dataType = "string", paramType = "header")
    )
    public ApiResult<String> delRole2User(@RequestBody DelRole2UserDto delRole2UserDto) {
        delRole2UserDto.setCreateOperator(operator);
        delRole2UserDto.setUpdateOperator(operator);
        return buildMsgPackage(userRoleService.delRole2User(delRole2UserDto));
    }
}
